home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 351-375 / 351 / pdc / pdcsrc.lzh / PDC / PreComp.c < prev    next >
C/C++ Source or Header  |  1990-04-06  |  23KB  |  1,036 lines

  1.  
  2. /* PDC Compiler - A Freely Distributable C Compiler for the Amiga
  3.  *                Based upon prior work by Matthew Brandt and Jeff Lydiatt.
  4.  *
  5.  * PDC Compiler release 3.3 Copyright (C) 1989 Paul Petersen and Lionel Hummel.
  6.  * PDC Software Distribution (C) 1989 Lionel Hummel and Paul Petersen.
  7.  *
  8.  * This code is freely redistributable upon the conditions that this 
  9.  * notice remains intact and that modified versions of this file not be 
  10.  * distributed as part of the PDC Software Distribution without the express
  11.  * consent of the copyright holders.
  12.  *
  13.  *------------------------------------------------------------------
  14.  *
  15.  * $Log:    PreComp.c,v $
  16.  * Revision 3.33  90/04/05  22:44:59  lionel
  17.  * None.
  18.  * 
  19.  * Revision 3.32  90/02/03  16:25:20  lionel
  20.  * None
  21.  * 
  22.  *------------------------------------------------------------------
  23.  */
  24.  
  25. /*
  26.  * PreComp.c - Generate and read precompiled header files
  27.  */
  28.  
  29. #include        <stdio.h>
  30. #include        "C.h"
  31. #include        "Expr.h"
  32. #include        "Gen.h"
  33. #include        "Cglbdec.h"
  34.  
  35. #if 0
  36. #define GENERATE_FMT
  37. #endif
  38.  
  39. extern FILE    *fopen();
  40. extern void     fclose(), exit(), fwrite();
  41. extern void     bzero();
  42. extern char    *litlate(), *itoa();
  43. extern void    *xalloc();
  44. extern int      strlen();
  45.  
  46. extern char     prepbuffer[];
  47.  
  48. extern TABLE    tagtable;
  49.  
  50. extern struct libcall   *libpragma;
  51.  
  52. void            read_tbl();
  53. void            dump_tbl();
  54. void            fmt_tbl2();
  55. void            fmt_type();
  56.  
  57. static FILE    *fp = NULL;
  58. static int      indent_level = 0;
  59.  
  60. #define MAXCHAIN    100
  61.  
  62. struct chain {
  63.     struct chain   *next;
  64.     int             entries;
  65.     void           *data[MAXCHAIN + 1];
  66. };
  67.  
  68. static struct chain *chead = NULL, *ctail = NULL;
  69.  
  70. enum e_comp {
  71.     TOPLEV_TBL, ENDOF_TBL,
  72.     TOPLEV_SYM, ENDOF_SYM,
  73.     TOPLEV_TYP, ENDOF_TYP,
  74.     TOPLEV_RSYM, ENDOF_RSYM,
  75.     TOPLEV_RTYP, ENDOF_RTYP,
  76.     TOPLEV_LIBENTRY, ENDOF_LIBENTRY,
  77.     TOPLEV_LIBCALL, ENDOF_LIBCALL
  78. };
  79.  
  80. static void
  81. putcomp1(val)
  82.     long            val;
  83. {
  84.     char            data = val;
  85.  
  86.     fwrite(&data, 1, sizeof(char), fp);
  87. }
  88.  
  89. static long
  90. getcomp1()
  91. {
  92.     char            val;
  93.  
  94.     fread(&val, 1, sizeof(char), fp);
  95.     return ((long) val);
  96. }
  97.  
  98. static void
  99. putcomp2(val)
  100.     long            val;
  101. {
  102.     short           data = val;
  103.  
  104.     fwrite(&data, 1, sizeof(short), fp);
  105. }
  106.  
  107. static short
  108. getcomp2()
  109. {
  110.     short           val;
  111.  
  112.     fread(&val, 1, sizeof(short), fp);
  113.     return ((long) val);
  114. }
  115.  
  116. static void
  117. putcomp4(val)
  118.     long            val;
  119. {
  120.     fwrite(&val, 1, sizeof(long), fp);
  121. }
  122.  
  123. static long
  124. getcomp4()
  125. {
  126.     long            val;
  127.  
  128.     fread(&val, 1, sizeof(long), fp);
  129.     return (val);
  130. }
  131.  
  132. static void
  133. putstrlit(s)
  134.     char           *s;
  135. {
  136.     long            count;
  137.  
  138.     if (s == NULL)
  139.         putcomp2(0);
  140.     else {
  141.         count = strlen(s) + 1;
  142.         putcomp2(count);
  143.         fwrite(s, 1, count, fp);
  144.     }
  145. }
  146.  
  147. static char    *
  148. getstrlit()
  149. {
  150.     long            count;
  151.  
  152.  
  153.     count = getcomp2();
  154.     if (count == 0)
  155.         return (NULL);
  156.     else {
  157.         fread(laststr, 1, count, fp);
  158.         return (litlate(laststr));
  159.     }
  160. }
  161.  
  162.  
  163. void           *
  164. get_recur(key)
  165.     int             key;
  166. {
  167.     int             i, index;
  168.     struct chain   *link;
  169.  
  170.     index = 0;
  171.     for (link = chead; link != NULL; link = link->next) {
  172.         for (i = 0; i < link->entries; ++i) {
  173.             ++index;
  174.             if (key == index)
  175.                 return (link->data[i]);
  176.         }
  177.     }
  178.     return (NULL);
  179. }
  180.  
  181. int
  182. check_recur(ptr)
  183.     void           *ptr;
  184. {
  185.     int             i, index;
  186.     struct chain   *link;
  187.  
  188.     index = 0;
  189.     for (link = chead; link != NULL; link = link->next) {
  190.         for (i = 0; i < link->entries; ++i) {
  191.             ++index;
  192.             if (ptr == link->data[i])
  193.                 return (index);
  194.         }
  195.     }
  196.     return (-1);
  197. }
  198.  
  199. void
  200. put_recur(ptr)
  201.     void           *ptr;
  202. {
  203.     struct chain   *link;
  204.  
  205.     if (ctail == NULL) {
  206.         chead = ctail = (struct chain *) xalloc(sizeof(struct chain));
  207.         bzero(ctail, sizeof(struct chain));
  208.     }
  209.     else if (ctail->entries >= MAXCHAIN) {
  210.         link = (struct chain *) xalloc(sizeof(struct chain));
  211.         bzero(link, sizeof(struct chain));
  212.         ctail->next = link;
  213.         ctail = link;
  214.     }
  215.     ctail->data[ctail->entries] = ptr;
  216.     ctail->entries += 1;
  217. }
  218.  
  219. void
  220. dump_type(tp)
  221.     TYP            *tp;
  222. {
  223.     int             index;
  224.  
  225.     if (tp != NULL) {
  226.         if ((index = check_recur(tp)) >= 0) {
  227.             putcomp1(TOPLEV_RTYP);
  228.             putcomp2(index);
  229.             putcomp1(ENDOF_RTYP);
  230.         }
  231.         else {
  232.             put_recur(tp);
  233.             putcomp1(TOPLEV_TYP);
  234.             putstrlit(tp->sname);
  235.             putcomp1(tp->type);
  236.             putcomp1(tp->val_flag);
  237.             putcomp4(tp->size);
  238.             dump_tbl(&(tp->lst));
  239.             dump_type(tp->btp);
  240.             putcomp1(ENDOF_TYP);
  241.         }
  242.     }
  243. }
  244.  
  245. void
  246. dump_union(sp)
  247.     SYM            *sp;
  248. {
  249.     switch (sp->storage_class) {
  250.     case sc_define:
  251.         putstrlit(sp->value.s);
  252.         break;
  253.     default:
  254.         putcomp4(sp->value.i);
  255.         break;
  256.     }
  257. }
  258.  
  259. void
  260. dump_symbol(sp)
  261.     SYM            *sp;
  262. {
  263.     int             index;
  264.  
  265.     if ((index = check_recur(sp)) >= 0) {
  266.         putcomp1(TOPLEV_RSYM);
  267.         putcomp2(index);
  268.         putcomp1(ENDOF_RSYM);
  269.     }
  270.     else {
  271.         put_recur(sp);
  272.         putcomp1(TOPLEV_SYM);
  273.         putstrlit(sp->name);
  274.         putcomp4(sp->key);
  275.         putcomp1(sp->storage_class);
  276.         putcomp1(sp->storage_type);
  277.         dump_union(sp);
  278.         dump_type(sp->tp);
  279.         putcomp1(ENDOF_SYM);
  280.     }
  281. }
  282.  
  283. void
  284. dump_libentry( lb )
  285.     struct libcall  *lb;
  286. {
  287.     putcomp1(TOPLEV_LIBENTRY);
  288.  
  289.     putstrlit( lb->basename );
  290.     putstrlit( lb->funcname );
  291.     putstrlit( lb->args     );
  292.     putstrlit( lb->offset   );
  293.  
  294.     putcomp1(ENDOF_LIBENTRY);
  295. }
  296.  
  297. void
  298. dump_libcall()
  299. {
  300.     struct libcall  *lb;
  301.  
  302.     putcomp1(TOPLEV_LIBCALL);
  303.  
  304.     for (lb = libpragma; lb != NULL; lb = lb->next) 
  305.         dump_libentry( lb );
  306.    
  307.     putcomp1(ENDOF_LIBCALL);
  308. }
  309.  
  310. void
  311. dump_tbl(tbl)
  312.     TABLE          *tbl;
  313. {
  314.     SYM            *sp;
  315.     int             index;
  316.  
  317.     putcomp1(TOPLEV_TBL);
  318.  
  319.     for (sp = tbl->head; sp != NULL; sp = sp->next) {
  320.         if ((index = check_recur(sp)) < 0)
  321.             dump_symbol(sp);
  322.         else {
  323.             putcomp1(TOPLEV_RSYM);
  324.             putcomp2(index);
  325.             putcomp1(ENDOF_RSYM);
  326.             break;
  327.         }
  328.     }
  329.     putcomp1(ENDOF_TBL);
  330. }
  331.  
  332. void
  333. dump_precomp(name)
  334.     char           *name;
  335. {
  336.     if ((fp = fopen(name, "w")) == NULL) {
  337.         fprintf(stderr, "Error in opening precomp file '%s' !\n", name );
  338.         exit(1);
  339.     }
  340.  
  341.     dump_tbl(&defsyms);
  342.     dump_tbl(&gsyms);
  343.     dump_tbl(&tagtable);
  344.  
  345.     dump_tbl(&cmd_local);
  346.  
  347.     dump_libcall();
  348.  
  349.     fclose(fp);
  350.  
  351.     chead = ctail = NULL;
  352. }
  353.  
  354. void           *
  355. read_recur(comp)
  356.     enum e_comp     comp;
  357. {
  358.     long            ctype;
  359.     int             index;
  360.  
  361.     index = getcomp2();
  362.     ctype = getcomp1();
  363.  
  364.     if ((enum e_comp) ctype != comp) {
  365.         fprintf(stderr, "Reading a RECUR, got [%d]\n", ctype );
  366.     }
  367.  
  368.     return (get_recur(index));
  369. }
  370.  
  371. void
  372. read_type(tp)
  373.     TYP            *tp;
  374. {
  375.     long            ctype;
  376.  
  377.     put_recur(tp);
  378.  
  379.     tp->sname = getstrlit();
  380.     tp->type = (enum e_bt) getcomp1();
  381.     tp->val_flag = getcomp1();
  382.     tp->size = getcomp4();
  383.  
  384.     read_tbl(&tp->lst);
  385.  
  386.     ctype = getcomp1();
  387.  
  388.     if ((enum e_comp) ctype == TOPLEV_RTYP) {
  389.         tp->btp = (TYP *) read_recur(ENDOF_RTYP);
  390.         ctype = getcomp1();
  391.     }
  392.     else if ((enum e_comp) ctype == TOPLEV_TYP) {
  393.         ++global_flag;
  394.         tp->btp = (TYP *) xalloc(sizeof(TYP));
  395.         --global_flag;
  396.         bzero(tp->btp, sizeof(TYP));
  397.         read_type(tp->btp);
  398.         ctype = getcomp1();
  399.     }
  400.     if ((enum e_comp) ctype != ENDOF_TYP) {
  401.         fprintf( stderr, "Reading a TYPE, got [%d]\n", ctype );
  402.     }
  403. }
  404.  
  405. void
  406. read_union(sp)
  407.     SYM            *sp;
  408. {
  409.     switch (sp->storage_class) {
  410.     case sc_define:
  411.         sp->value.s = getstrlit();
  412.         break;
  413.     default:
  414.         sp->value.i = getcomp4();
  415.         break;
  416.     }
  417. }
  418.  
  419. void
  420. read_symbol(sp)
  421.     SYM            *sp;
  422. {
  423.     long            ctype;
  424.  
  425.     put_recur(sp);
  426.  
  427.     sp->name = getstrlit();
  428.     sp->key = getcomp4();
  429.     sp->storage_class = (enum e_sc) getcomp1();
  430.     sp->storage_type = (enum e_sc) getcomp1();
  431.     read_union(sp);
  432.  
  433.     ctype = getcomp1();
  434.  
  435.     if ((enum e_comp) ctype == TOPLEV_RTYP) {
  436.         sp->tp = (TYP *) read_recur(ENDOF_RTYP);
  437.         ctype = getcomp1();
  438.     }
  439.     else if ((enum e_comp) ctype == TOPLEV_TYP) {
  440.         ++global_flag;
  441.         sp->tp = (TYP *) xalloc(sizeof(TYP));
  442.         --global_flag;
  443.         bzero(sp->tp, sizeof(TYP));
  444.         read_type(sp->tp);
  445.         ctype = getcomp1();
  446.     }
  447.     if ((enum e_comp) ctype != ENDOF_SYM) {
  448.         fprintf(stderr, "Reading a SYMBOL, got [%d]\n", ctype );
  449.     }
  450. }
  451.  
  452. void
  453. read_libentry( lb )
  454.     struct libcall  *lb;
  455. {
  456.     long    ctype;
  457.  
  458.     lb->basename = getstrlit();
  459.     lb->funcname = getstrlit();
  460.     lb->args     = getstrlit();
  461.     lb->offset   = getstrlit();
  462.  
  463.     ctype = getcomp1();
  464.  
  465.     if ((enum e_comp) ctype != ENDOF_LIBENTRY) {
  466.         fprintf(stderr, "Reading a LIBENTRY, got [%d]\n", ctype );
  467.     }
  468. }
  469.  
  470. void
  471. read_libcall()
  472. {
  473.     long            ctype;
  474.  
  475.     struct libcall  *lb;
  476.  
  477.     ctype = getcomp1();
  478.  
  479.     if ((enum e_comp) ctype != TOPLEV_LIBCALL) {
  480.         fprintf(stderr, "Reading a LIBCALL start, got [%d]\n", ctype );
  481.         exit(1);
  482.     }
  483.  
  484.     libpragma = NULL;
  485.  
  486.     for (;;) {
  487.         switch (ctype = getcomp1()) {
  488.         case ENDOF_LIBCALL:
  489.             return;
  490.         case TOPLEV_LIBENTRY:
  491.             ++global_flag;
  492.             lb = (struct libcall *) xalloc(sizeof(struct libcall));
  493.             --global_flag;
  494.  
  495.             bzero(lb, sizeof(struct libcall));
  496.             read_libentry(lb);
  497.  
  498.             lb->next = libpragma;
  499.             libpragma = lb;
  500.  
  501.             break;
  502.         default:
  503.             fprintf(stderr, "Reading a LIBCALL, got [%d]\n", ctype );
  504.             return;
  505.         }
  506.     }
  507. }
  508.  
  509. void
  510. read_tbl(tbl)
  511.     TABLE          *tbl;
  512. {
  513.     long            ctype;
  514.  
  515.     SYM            *sp;
  516.  
  517.     ctype = getcomp1();
  518.  
  519.     if ((enum e_comp) ctype != TOPLEV_TBL) {
  520.         fprintf(stderr, "Reading a TABLE start, got [%d]\n", ctype );
  521.         exit(1);
  522.     }
  523.  
  524.     bzero(tbl, sizeof(TABLE));
  525.  
  526.     for (;;) {
  527.         switch (ctype = getcomp1()) {
  528.         case ENDOF_TBL:
  529.             return;
  530.         case TOPLEV_RSYM:
  531.             sp = (SYM *) read_recur(ENDOF_RSYM);
  532.             if (tbl->head == NULL)
  533.                 tbl->head = tbl->tail = sp;
  534.             else
  535.                 tbl->tail->next = sp;
  536.             while (tbl->tail->next != NULL)
  537.                 tbl->tail = tbl->tail->next;
  538.             break;
  539.         case TOPLEV_SYM:
  540.             ++global_flag;
  541.             sp = (SYM *) xalloc(sizeof(SYM));
  542.             --global_flag;
  543.             bzero(sp, sizeof(SYM));
  544.             read_symbol(sp);
  545.             if (tbl->head == NULL)
  546.                 tbl->head = tbl->tail = sp;
  547.             else
  548.                 tbl->tail->next = sp;
  549.             while (tbl->tail->next != NULL)
  550.                 tbl->tail = tbl->tail->next;
  551.             break;
  552.         default:
  553.             fprintf(stderr, "Reading a TABLE, got [%d]\n", ctype );
  554.             return;
  555.         }
  556.     }
  557. }
  558.  
  559. void
  560. read_precomp(name)
  561.     char           *name;
  562. {
  563.     if ((fp = fopen(name, "r")) == NULL) {
  564.         fprintf(stderr, "Error in opening precomp file '%s'!\n", name );
  565.         exit(1);
  566.     }
  567.  
  568.     read_tbl(&defsyms);
  569.     read_tbl(&gsyms);
  570.     read_tbl(&tagtable);
  571.  
  572.     read_tbl(&cmd_include);
  573.  
  574.     read_libcall();
  575.  
  576.     fclose(fp);
  577.  
  578.     chead = ctail = NULL;
  579. }
  580.  
  581.  
  582. #ifndef GENERATE_FMT
  583.  
  584. void fmt_precomp() { }
  585.  
  586. #else
  587.  
  588. static void
  589. prepend(s1)
  590.     char           *s1;
  591. {
  592.     char           *ptr;
  593.     int             len, ofs = strlen(s1);
  594.  
  595.     len = strlen(prepbuffer);
  596.     for (ptr = &prepbuffer[len]; len >= 0; --ptr, --len)
  597.         ptr[ofs] = *ptr;
  598.     ptr = prepbuffer;
  599.     while (*s1)
  600.         *ptr++ = *s1++;
  601. }
  602.  
  603. static void
  604. append(s1)
  605.     char           *s1;
  606. {
  607.     strcat(prepbuffer, s1);
  608. }
  609.  
  610. void
  611. fmt_indent()
  612. {
  613.     int             i;
  614.     char buffer[1024], *cp;
  615.  
  616.     cp = &buffer[0];
  617.     i = (indent_level > 1023 ? 1023 : indent_level);
  618.     while (i--)
  619.         *cp++ = " ";
  620.     *cp = '\0';
  621.     fprintf(fp, "%s", buffer);
  622. }
  623.  
  624. void
  625. fmt_aux(tp)
  626.     TYP            *tp;
  627. {
  628.     char            hold[80];
  629.  
  630.     strcpy(hold, prepbuffer);
  631.     fmt_tbl2(tp, "");
  632.     strcpy(prepbuffer, hold);
  633. }
  634.  
  635. void
  636. fmt_func(tp)
  637.     TYP            *tp;
  638. {
  639.     SYM            *sp;
  640.     char            hold[256];
  641.  
  642.     append("(");
  643.     strcpy(hold, prepbuffer);
  644.     sp = tp->lst.head;
  645.     if (sp != NULL) {
  646.         strcpy(prepbuffer, sp->name != NULL ? sp->name : "");
  647.         fmt_type(sp->tp, bt_unknown);
  648.         strcat(hold, prepbuffer);
  649.         for (sp = sp->next; sp != NULL; sp = sp->next) {
  650.             strcpy(prepbuffer, sp->name != NULL ? sp->name : "");
  651.             fmt_type(sp->tp, bt_unknown);
  652.             strcat(hold, ", ");
  653.             strcat(hold, prepbuffer);
  654.         }
  655.     }
  656.     strcpy(prepbuffer, hold);
  657.     append(")");
  658. }
  659.  
  660. void
  661. fmt_type(tp, prev)
  662.     TYP            *tp;
  663.     enum e_bt       prev;
  664. {
  665.     int             len;
  666.  
  667.     switch (tp->type) {
  668.     case bt_pointer:
  669.         if (tp->val_flag) {
  670.             if (prev == bt_pointer) {
  671.                 prepend("(");
  672.                 append(")");
  673.             }
  674.             len = strlen(prepbuffer);
  675.             if (tp->size <= 0)
  676.                 append("[]");
  677.             else {
  678.                 prepbuffer[len] = '[';
  679.                 strcpy( &prepbuffer[len+1], itoa( tp->size / tp->btp->size ));
  680.                 strcat( &prepbuffer[len], "]" );
  681.             }
  682.             fmt_type(tp->btp, bt_unknown);
  683.         }
  684.         else {
  685.             prepend("*");
  686.             fmt_type(tp->btp, bt_pointer);
  687.         }
  688.         break;
  689.     case bt_char:
  690.         prepend("char ");
  691.         break;
  692.     case bt_uchar:
  693.         prepend("unsigned char ");
  694.         break;
  695.     case bt_short:
  696.         prepend("short ");
  697.         break;
  698.     case bt_ushort:
  699.         prepend("unsigned short ");
  700.         break;
  701.     case bt_unsigned:
  702.         prepend("unsigned int ");
  703.         break;
  704.     case bt_long:
  705.         prepend("long ");
  706.         break;
  707.     case bt_float:
  708.         prepend("float ");
  709.         break;
  710.     case bt_double:
  711.         prepend("double ");
  712.         break;
  713.     case bt_struct:
  714.         if (tp->sname == NULL)
  715.             fmt_aux(tp);
  716.         else {
  717.             prepend(" ");
  718.             prepend(tp->sname);
  719.             prepend("struct ");
  720.         }
  721.         break;
  722.     case bt_union:
  723.         if (tp->sname == NULL)
  724.             fmt_aux(tp);
  725.         else {
  726.             prepend(" ");
  727.             prepend(tp->sname);
  728.             prepend("union ");
  729.         }
  730.         break;
  731.     case bt_enum:
  732.         if (tp->sname == NULL)
  733.             fmt_aux(tp);
  734.         else {
  735.             prepend(" ");
  736.             prepend(tp->sname);
  737.             prepend("enum ");
  738.         }
  739.         break;
  740.     case bt_func:
  741.         if (prev == bt_pointer) {
  742.             prepend("(");
  743.             append(")");
  744.         }
  745.         fmt_func(tp);
  746.         fmt_type(tp->btp, bt_unknown);
  747.         break;
  748.     case bt_ifunc:
  749.         if (prev == bt_pointer) {
  750.             prepend("(");
  751.             append(")");
  752.         }
  753.         fmt_func(tp);
  754.         fmt_type(tp->btp, bt_unknown);
  755.         break;
  756.     case bt_void:
  757.         prepend("void ");
  758.         break;
  759.     case bt_unknown:
  760.         prepend("ERROR *2 ");
  761.         break;
  762.     }
  763. }
  764.  
  765. void
  766. fmt_symbol(sp)
  767.     SYM            *sp;
  768. {
  769.     if (sp != NULL && sp->tp != NULL) {
  770.         strcpy(prepbuffer, (sp->name != NULL ? sp->name : ""));
  771.         fmt_type(sp->tp, bt_unknown);
  772.         fprintf(fp, "%s;\n", prepbuffer );
  773.     }
  774. }
  775.  
  776. void
  777. fmt_tags(tbl)
  778.     TABLE          *tbl;
  779. {
  780.     SYM            *sp, *sp1;
  781.     int             count;
  782.  
  783.     for (sp = tbl->head; sp != NULL; sp = sp->next) {
  784.         if (sp->tp != NULL) {
  785.             switch (sp->storage_class) {
  786.             case sc_const:  /* Ignore enum labels */
  787.                 break;
  788.             case sc_type:
  789.                 switch (sp->tp->type) {
  790.                 case bt_enum:
  791.                     fprintf(fp, "enum %s {\n", sp->name );
  792.                     indent_level += 4;
  793.                     sp1 = sp->tp->lst.head;
  794.                     if (sp1 != NULL) {
  795.                         fmt_indent();
  796.                         fprintf( fp, "%s", sp1->name );
  797.                         count = 1;
  798.                         for (sp1 = sp1->next; sp1 != NULL; sp1 = sp1->next) {
  799.                             ++count;
  800.                             fprintf( fp, ", ");
  801.                             if (count > 5) {
  802.                                 count = 1;
  803.                                 fprintf(fp, "\n");
  804.                                 fmt_indent();
  805.                             }
  806.                             fprintf( fp, "%s", sp1->name );
  807.                         }
  808.                     }
  809.                     indent_level -= 4;
  810.                     fprintf( fp, "\n");
  811.                     fmt_indent();
  812.                     fprintf( fp, "};\n\n");
  813.                     break;
  814.                 case bt_union:
  815.                     fprintf(fp, "union %s {\n", sp->name );
  816.                     indent_level += 4;
  817.                     sp1 = sp->tp->lst.head;
  818.                     if (sp1 != NULL) {
  819.                         fmt_indent();
  820.                         fmt_symbol(sp1);
  821.                         for (sp1 = sp1->next; sp1 != NULL; sp1 = sp1->next) {
  822.                             fmt_indent();
  823.                             fmt_symbol(sp1);
  824.                         }
  825.                     }
  826.                     indent_level -= 4;
  827.                     fmt_indent();
  828.                     fprintf( fp, "};\n\n");
  829.                     break;
  830.                 case bt_struct:
  831.                     fprintf(fp, "struct %s {\n", sp->name );
  832.                     indent_level += 4;
  833.                     sp1 = sp->tp->lst.head;
  834.                     if (sp1 != NULL) {
  835.                         fmt_indent();
  836.                         fmt_symbol(sp1);
  837.                         for (sp1 = sp1->next; sp1 != NULL; sp1 = sp1->next) {
  838.                             fmt_indent();
  839.                             fmt_symbol(sp1);
  840.                         }
  841.                     }
  842.                     indent_level -= 4;
  843.                     fmt_indent();
  844.                     fprintf( fp, "};\n\n");
  845.                     break;
  846.                 }
  847.                 break;
  848.             }
  849.         }
  850.     }
  851. }
  852.  
  853. void
  854. fmt_tbl2(tp, name)
  855.     TYP            *tp;
  856.     char           *name;
  857. {
  858.     SYM            *sp1;
  859.  
  860.     if (tp != NULL) {
  861.         switch (tp->type) {
  862.         case bt_enum:
  863.             fprintf(fp, "enum %s {\n", name );
  864.             indent_level += 4;
  865.             sp1 = tp->lst.head;
  866.             fpprintf( fp, sp1->name );
  867.             for (sp1 = sp1->next; sp1 != NULL; sp1 = sp1->next) {
  868.                 fprintf( fp, ",%s", sp1->name );
  869.             }
  870.             indent_level -= 4;
  871.             fmt_indent();
  872.             fprintf( fp, "} ");
  873.             break;
  874.         case bt_union:
  875.             fprintf(fp, "union %s {\n", name );
  876.             indent_level += 4;
  877.             sp1 = tp->lst.head;
  878.             fmt_indent();
  879.             fmt_symbol(sp1);
  880.             for (sp1 = sp1->next; sp1 != NULL; sp1 = sp1->next) {
  881.                 fmt_indent();
  882.                 fmt_symbol(sp1);
  883.             }
  884.             indent_level -= 4;
  885.             fmt_indent();
  886.             fprintf( fp, "} ");
  887.             break;
  888.         case bt_struct:
  889.             fprintf(fp, "struct %s {\n", name );
  890.             indent_level += 4;
  891.             sp1 = tp->lst.head;
  892.             fmt_indent();
  893.             fmt_symbol(sp1);
  894.             for (sp1 = sp1->next; sp1 != NULL; sp1 = sp1->next) {
  895.                 fmt_indent();
  896.                 fmt_symbol(sp1);
  897.             }
  898.             indent_level -= 4;
  899.             fmt_indent();
  900.             fprintf( fp, "} " );
  901.             break;
  902.         case bt_typedef:
  903.             fprintf(fp, "typedef " );
  904.             strcpy(prepbuffer, name);
  905.             fmt_type(tp->btp, bt_unknown);
  906.             fprintf(fp, "%s", name );
  907.             break;
  908.         }
  909.     }
  910. }
  911.  
  912. void
  913. fmt_tbl(tbl)
  914.     TABLE          *tbl;
  915. {
  916.     SYM            *sp;
  917.  
  918.     for (sp = tbl->head; sp != NULL; sp = sp->next) {
  919.         switch (sp->storage_class) {
  920.         case sc_const:
  921.             break;
  922.         case sc_type:
  923.             fmt_tbl2(sp->tp, sp->name);
  924.             fprintf(fp, ";\n\n" );
  925.             break;
  926.         case sc_external:
  927.             if (sp != NULL && sp->tp != NULL) {
  928.                 fprintf(fp, "extern " );
  929.                 fmt_symbol(sp);
  930.             }
  931.             break;
  932.         case sc_static:
  933.             if (sp != NULL && sp->tp != NULL) {
  934.                 fprintf( fp, "static " );
  935.                 fmt_symbol(sp);
  936.             }
  937.             break;
  938.         default:
  939.             fmt_symbol(sp);
  940.             break;
  941.         }
  942.     }
  943. }
  944.  
  945. void
  946. fmt_libentry( lb )
  947.     struct libcall  *lb;
  948. {
  949.     fprintf( fp, "#pragma libcall %s %s %s %s\n",
  950.              lb->basename, lb->funcname, lb->offset, lb->args );
  951. }
  952.  
  953. void
  954. fmt_libcall()
  955. {
  956.     struct libcall  *lb;
  957.  
  958.     for (lb = libpragma; lb != NULL; lb = lb->next) 
  959.         fmt_libentry( lb );
  960. }
  961.  
  962.  
  963. void
  964. fmt_define(tbl)
  965.     TABLE          *tbl;
  966. {
  967.     int             len;
  968.     SYM            *sp, *sp1;
  969.  
  970.     for (sp = tbl->head; sp != NULL; sp = sp->next) {
  971.         fprintf( fp, "#define %s", sp->name);
  972.         if (sp->tp != NULL && (sp1 = sp->tp->lst.head) != NULL) {
  973.             fprintf( fp, "(%s", sp1->name );
  974.             for (sp1 = sp1->next; sp1 != NULL; sp1 = sp1->next) {
  975.                 fprintf( fp, ",%s", sp1->name );
  976.             }
  977.             fprintf( fp, ") " );
  978.         }
  979.         if (sp->value.s != NULL) {
  980.             for (len = strlen(sp->value.s) - 1; len >= 0; --len) {
  981.                 if (sp->value.s[len] != '\n')
  982.                     break;
  983.                 sp->value.s[len] = ' ';
  984.             }
  985.             fprintf( fp, " %s", sp->value.s );
  986.         }
  987.         fprintf( fp, "\n" );
  988.     }
  989. }
  990.  
  991. void
  992. fmt_include(tbl)
  993.     TABLE          *tbl;
  994. {
  995.     int             len;
  996.     SYM            *sp, *sp1;
  997.  
  998.     for (sp = tbl->head; sp != NULL; sp = sp->next) {
  999.         fprintf( "#include ", fp );
  1000.         if (sp->value.i) {
  1001.             fprintf( fp, "#include <%s>\n", sp-name);
  1002.         }
  1003.         else {
  1004.             fprintf( fp, "#include \"%s\"\n", sp-name);
  1005.         }
  1006.     }
  1007. }
  1008.  
  1009. void
  1010. fmt_precomp(name)
  1011.     char           *name;
  1012. {
  1013.     char *comment_string = "\n/* ------------------------------ */\n\n" ;
  1014.  
  1015.     if ((fp = fopen(name, "w")) == NULL) {
  1016.         fprintf( stderr, "Error in opening precomp file '%s' !\n", name );
  1017.         exit(1);
  1018.     }
  1019.     fprintf( fp, comment_string );
  1020.     fmt_define(&defsyms);
  1021.     fprintf( fp, comment_string );
  1022.     fmt_tags(&tagtable);
  1023.     fprintf( fp, comment_string );
  1024.     fmt_tbl(&gsyms);
  1025.     fprintf( fp, comment_string );
  1026.     fmt_libcall();
  1027.     fprintf( fp, comment_string );
  1028.     fmt_include(&cmd_local);
  1029.  
  1030.     fclose(fp);
  1031.  
  1032.     chead = ctail = NULL;
  1033. }
  1034.  
  1035. #endif
  1036.